package com.meilai.project.core.excel;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.meilai.project.core.excel.config.QueryParamConfig;
import com.meilai.project.core.excel.config.TableHeaderConfig;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;

import java.util.Date;
import java.util.List;

/**
 * @author xchen
 * @since 2022-02-15
 */
public class DefaultSheetGenerator extends AbstractSheetGenerator {

	private CellStyle tableBodyCellStyle;
	private CellStyle tableHeaderCellStyle;
	private CellStyle titleCellStyle;
	private CellStyle exportTimeStyle;
	private Boolean hasGenerateHeader = false;

	@Override
	public void initSheetGenerator() {
		tableBodyCellStyle = createCommonCellStyle(10, false);
		tableHeaderCellStyle = createCommonCellStyle(12, true);
		titleCellStyle = createTitleCellStyle((short) 16);
		exportTimeStyle = createExportTimeCellStyle();
	}

	@Override
	public void process(List data) {
		if (!hasGenerateHeader) {
			generateTitle();
			generateExportTime();
			generateQueryParams();
			generateBlankRow();
			generateTableHeader();
			hasGenerateHeader = true;
		}
		generateTableBody(data);
	}

	protected void generateBlankRow() {
		currentRowIndex++;
		sheet.createRow(currentRowIndex);
	}

	//生成title
	protected void generateTitle() {
		if (StrUtil.isEmpty(reportSheet.getReportTitle())) {
			return;
		}
		currentRowIndex++;
		sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, reportSheet.getTableHeaderConfigList().size() - 1));
		SXSSFRow titleRow = sheet.createRow(currentRowIndex);
		titleRow.setHeight((short) 600);
		SXSSFCell cell = titleRow.createCell(0);
		cell.setCellValue(reportSheet.getReportTitle());
		cell.setCellStyle(titleCellStyle);
	}

	//导出时间
	protected void generateExportTime() {
		if (StrUtil.isEmpty(reportSheet.getReportTitle())) {
			return;
		}
		currentRowIndex++;
		sheet.addMergedRegion(new CellRangeAddress(currentRowIndex, currentRowIndex, 0, 2)); // 跨两行
		SXSSFRow row = sheet.createRow(currentRowIndex);
		SXSSFCell cell = row.createCell(0);
		cell.setCellValue("导出时间：" + DateUtil.format(new Date(), "yyyy/MM/dd HH:mm:ss"));
		cell.setCellStyle(exportTimeStyle);
	}

	//生成查询参数
	protected void generateQueryParams() {
		List<QueryParamConfig> queryParamConfigList = reportSheet.getQueryParamConfigList();
		if (CollUtil.isEmpty(queryParamConfigList)) {
			return;
		}
		//列总数
		currentRowIndex++;
		SXSSFRow labelRow = sheet.createRow(currentRowIndex);
		currentRowIndex++;
		SXSSFRow valueRow = sheet.createRow(currentRowIndex);
		for (int i = 0; i < queryParamConfigList.size(); i++) {
			QueryParamConfig paramConfig = queryParamConfigList.get(i);
			SXSSFCell labelCell = labelRow.createCell(i);
			SXSSFCell valueCell = valueRow.createCell(i);
			labelCell.setCellValue(paramConfig.getLabel());
			valueCell.setCellValue(paramConfig.getValue());
		}
	}

	//生成表头
	protected void generateTableHeader() {
		currentRowIndex++;
		SXSSFRow row = sheet.createRow(currentRowIndex);
		List<TableHeaderConfig> tableHeaderConfigList = reportSheet.getTableHeaderConfigList();
		for (int i = 0; i < tableHeaderConfigList.size(); i++) {
			TableHeaderConfig tableHeaderConfig = tableHeaderConfigList.get(i);
			SXSSFCell cell = row.createCell(i);
			cell.setCellValue(tableHeaderConfig.getLabel());
			cell.setCellStyle(tableHeaderCellStyle);
		}
	}

	//生成表体
	protected void generateTableBody(List list) {
		for (Object item : list) {
			currentRowIndex++;
			SXSSFRow row = sheet.createRow(currentRowIndex);
			List<TableHeaderConfig> tableHeaderConfigList = reportSheet.getTableHeaderConfigList();
			for (int i = 0; i < tableHeaderConfigList.size(); i++) {
				String value = tableHeaderConfigList.get(i).getValue(item);
				SXSSFCell cell = row.createCell(i);
				cell.setCellStyle(tableBodyCellStyle);
				cell.setCellValue(value);
			}
		}
	}

	@Override
	public void afterProcess() {
		List<TableHeaderConfig> tableHeaderConfigList = reportSheet.getTableHeaderConfigList();
		for (int i = 0; i < tableHeaderConfigList.size(); i++) {
			TableHeaderConfig tableHeaderConfig = tableHeaderConfigList.get(i);
			if (null != tableHeaderConfig.getWidth()) {
				sheet.setColumnWidth(i, tableHeaderConfig.getWidth());
			} else {
				sheet.setColumnWidth(i, tableHeaderConfig.getLabel().getBytes().length * 256);
			}
		}
	}

}
